package com.tedu;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
//RetentionPolicy.SOURCE:它将被限定在Java源文件中，那么这个注解即不会参与编译也不会在运行期起任何作用，这个注解就和一个注释是一样的效果，只能被阅读Java文件的人看到；
//RetentionPolicy.CLASS:它将被编译到Class文件中，那么编译器可以在编译时根据注解做一些处理动作，但是运行时JVM（Java虚拟机）会忽略它，我们在运行期也不能读取到；
//RetentionPolicy.RUNTIME:这个注解可以在运行期的加载阶段被加载到Class对象中。那么在程序运行阶段，我们可以通过反射得到这个注解，并通过判断是否有这个注解或这个注解中属性的值，从而执行不同的程序代码段。
//实际开发中的自定义注解几乎都是使用的RetentionPolicy.RUNTIME；
//在默认的情况下，自定义注解是使用的RetentionPolicy.CLASS
@Target(ElementType.TYPE)
//@Target(value = {ElementType.METHOD,ElementType.TYPE})
//TYPE标明该注解可以用于类、接口（包括注解类型）或enum声明
//FIELD标明该注解可以用于字段(域)声明，包括enum实例
//METHOD标明该注解可以用于方法声明
//ANNOTATION_TYPE标明注解可以用于注解声明(应用于另一个注解上)
//PACKAGE标明注解可以用于包声明
@interface ZJ{
    public String name();//修饰符“public”对于接口方法是多余的
    int age();
    int[] array() default {99,88,100};
    boolean showSupport() default false;
}

public class zjTest {
    public static void main(String[] args) throws Exception {
        //获取类对象
        Class<?> c = Class.forName("com.tedu.Test");
        //判断该类对象上是否有添加注解
        boolean annotationPresent = c.isAnnotationPresent(ZJ.class);
        if (annotationPresent){
            //获取注解的对象
            ZJ zj = c.getAnnotation(ZJ.class);
            System.out.println("该类上有注解，获取注解中的信息");
            System.out.println("name:"+zj.name()+",age:"+zj.age()+",array:"+zj.array()[0]);
        }else {
            System.out.println("该类上没有注解");
        }
    }
}

@ZJ(name = "张三",age=18)
class Test{
    public void test(){
        System.out.println("ttt");
    }
}
